unit uCommandReader;

interface

uses
  SysUtils, Dialogs, uMap, uRoom, uTileSet, uTile, uObject, uFileSystem, uAction;

var
  parented: Integer;
  editType: Integer;
  whichOfType, whichOfType2, whichOfType3: Integer;

procedure beginRead();
procedure getWith(const variable: String; const value: String; var map: TGameMap);
function setWith(const map: TGameMap): String;

implementation

procedure beginRead();
begin
  parented := 0;
  editType := 0;
  whichOfType := 0;
  whichOfType2 := 0;
  whichOfType3 := 0;
end;

procedure getWith(const variable: String; const value: String; var map: TGameMap);
var
  i, j, k: Integer;
begin
  if (editType = 0) then
    begin
      if (variable = '0') then
        begin
          map.name := value;
        end;
      if (variable = '0{') then
        begin
          editType := 1;
          whichOfType := StrToInt(value);
          if (high(map.rooms) < whichOfType) then
            begin
              SetLength(map.rooms, whichOfType+1);
            end;
          parented := parented + 1;
        end;
      if (variable = '1{') then
        begin
          editType := 2;
          whichOfType := StrToInt(value);
          if (high(map.tileSets) < whichOfType) then
            begin
              SetLength(map.tileSets, whichOfType+1);
            end;
          map.tileSets[whichOfType] := TGameTileset.Create();
          parented := parented + 1;
        end;
    end
  else if (editType = 2) then
    begin
      if (variable = '0') then
        begin
          map.tileSets[whichOfType].name := value;
          map.tileSets[whichOfType].load(false);
        end;
      if (variable = '1}') then
        begin
          editType := StrToInt(value);
          parented := parented - 1;
        end;
    end
  else if (editType = 1) then
    begin
      if (variable = '0') then
        begin
          map.rooms[whichOfType].name := value;
        end;
      if (variable = '1') then
        begin
          map.rooms[whichOfType].width := StrToInt(value);
          SetLength(map.rooms[whichOfType].tiles, map.rooms[whichOfType].width);
          SetLength(map.rooms[whichOfType].objects, map.rooms[whichOfType].width);
        end;
      if (variable = '2') then
        begin
          map.rooms[whichOfType].height := StrToInt(value);
          for i := 0 to map.rooms[whichOfType].width-1 do
            begin
              SetLength(map.rooms[whichOfType].tiles[i], map.rooms[whichOfType].height);
              SetLength(map.rooms[whichOfType].objects[i], map.rooms[whichOfType].height);
            end;
        end;
      if (variable = '3') then
        begin
          if (value = '1') then
            begin
              map.rooms[whichOfType].willShowName := true;
            end
          else if (value = '0') then
            begin
              map.rooms[whichOfType].willShowName := false;
            end;
        end;
      if (variable = '0{') then
        begin
          editType := 3;
          whichOfType2 := StrToInt(value);
          parented := parented + 1;
        end;
      if (variable = '1{') then
        begin
          editType := 4;
          whichOfType2 := StrToInt(value);
          parented := parented + 1;
        end;
      if (variable = '0}') then
        begin
          editType := StrToInt(value);
          parented := parented - 1;
        end;
    end
  else if (editType = 3) then
    begin
      j := 0;
      i := whichOfType2;
      while (i > high(map.rooms[whichOfType].tiles)) do
        begin
          j := j + 1;
          i := i - length(map.rooms[whichOfType].tiles);
        end;
      if (high(map.rooms[whichOfType].tiles) < i) then
        begin
          setLength(map.rooms[whichOfType].tiles, i+1);
        end;
      for k := low(map.rooms[whichOfType].tiles) to high(map.rooms[whichOfType].tiles) do
        begin
          if (high(map.rooms[whichOfType].tiles[k]) < j) then
            begin
              setLength(map.rooms[whichOfType].tiles[k], j+1);
            end;
        end;

      if (variable = '0') then
        begin
          map.rooms[whichOfType].tiles[i, j].tileSet := map.tileSets[StrToInt(value)];
        end;
      if (variable = '1') then
        begin
          if (value = '1') then
            begin
              map.rooms[whichOfType].tiles[i, j].isWater := true;
            end
          else if (value = '0') then
            begin
              map.rooms[whichOfType].tiles[i, j].isWater := false;
            end;
        end;
      if (variable = '2') then
        begin
          if (value = '1') then
            begin
              map.rooms[whichOfType].tiles[i, j].isGorge := true;
            end
          else if (value = '0') then
            begin
              map.rooms[whichOfType].tiles[i, j].isGorge := false;
            end;
        end;
      if (variable = '3') then
        begin
          if (value = '1') then
            begin
              map.rooms[whichOfType].tiles[i, j].isGhosty := true;
            end
          else if (value = '0') then
            begin
              map.rooms[whichOfType].tiles[i, j].isGhosty := false;
            end;
        end;
      if (variable = '4') then
        begin
          map.rooms[whichOfType].tiles[i, j].tileTexture := StrToInt(value);
        end;
      if (variable = '5') then
        begin
          if (value = '1') then
            begin
              map.rooms[whichOfType].tiles[i, j].transparent := true;
            end
          else if (value = '0') then
            begin
              map.rooms[whichOfType].tiles[i, j].transparent := false;
            end;
        end;
      if (variable = '0}') then
        begin
          editType := StrToInt(value);
          parented := parented - 1;
        end;
    end
  else if (editType = 4) then
    begin
      j := 0;
      i := whichOfType2;
      while (i > high(map.rooms[whichOfType].objects)) do
        begin
          j := j + 1;
          i := i - length(map.rooms[whichOfType].objects);
        end;
      if (high(map.rooms[whichOfType].objects) < i) then
        begin
          setLength(map.rooms[whichOfType].objects, i+1);
        end;
      for k := low(map.rooms[whichOfType].objects) to high(map.rooms[whichOfType].objects) do
        begin
          if (high(map.rooms[whichOfType].objects[k]) < j) then
            begin
              setLength(map.rooms[whichOfType].objects[k], j+1);
            end;
        end;

      if (variable = '0') then
        begin
          map.rooms[whichOfType].objects[i, j].texture := map.tileSets[StrToInt(value)];
        end;
      if (variable = '1') then
        begin
          map.rooms[whichOfType].objects[i, j].objectType := value;
        end;
      if (variable = '2') then
        begin
          map.rooms[whichOfType].objects[i, j].text1 := value;
        end;
      if (variable = '3') then
        begin
          map.rooms[whichOfType].objects[i, j].text2 := value;
        end;
      if (variable = '4') then
        begin
          map.rooms[whichOfType].objects[i, j].texturePosition := StrToInt(value);
        end;
      if (variable = '5') then
        begin
          if (value = '1') then
            begin
              map.rooms[whichOfType].objects[i, j].isLiving := true;
            end
          else if (value = '0') then
            begin
              map.rooms[whichOfType].objects[i, j].isLiving := false;
            end;
        end;
      if (variable = '0{') then
        begin
          editType := 5;
          whichOfType3 := StrToInt(value);
          if (high(map.rooms[whichOfType].objects[i, j].actions) < whichOfType3) then
            begin
              setLength(map.rooms[whichOfType].objects[i, j].actions, whichOfType3+1);
            end;
          map.rooms[whichOfType].objects[i, j].actions[whichOfType3] := TGameAction.Create();
          parented := parented + 1;
        end;
      if (variable = '1}') then
        begin
          editType := StrToInt(value);
          parented := parented - 1;
        end;
    end
  else if (editType = 5) then
    begin
      j := 0;
      i := whichOfType2;
      while (i > high(map.rooms[whichOfType].objects)) do
        begin
          j := j + 1;
          i := i - length(map.rooms[whichOfType].objects);
        end;
      if (variable = '0') then
        begin
          map.rooms[whichOfType].objects[i, j].actions[whichOfType3].actionType := value;
        end;
      if (variable = '1') then
        begin
          map.rooms[whichOfType].objects[i, j].actions[whichOfType3].arguments := value;
        end;
      if (variable = '0}') then
        begin
          editType := StrToInt(value);
          parented := parented - 1;
        end;
    end;
end;

function setWith(const map: TGameMap): String;
var
  i, j, k, l, m, n: Integer;
  s: String;
begin
  s := '';
  s := s + '0=' + map.name + '_';
  for i := low(map.tileSets) to high(map.tileSets) do
    begin
      s := s + '1{=' + IntToStr(i) + '_';
      s := s + '0=' + map.tileSets[i].name + '_';
      s := s + '1}=' + '0' + '_';
    end;
  for i := low(map.rooms) to high(map.rooms) do
    begin
      s := s + '0{=' + IntToStr(i) + '_';
      s := s + '0=' + map.rooms[i].name + '_';
      s := s + '1=' + IntToStr(map.rooms[i].width) + '_';
      s := s + '2=' + IntToStr(map.rooms[i].height) + '_';
      if (map.rooms[i].willShowName = true) then s := s + '3=' + '1' + '_';
      if (map.rooms[i].willShowName = false) then s := s + '3=' + '0' + '_';
      for j := low(map.rooms[i].tiles) to high(map.rooms[i].tiles) do
        begin
          for k := low(map.rooms[i].tiles[j]) to high(map.rooms[i].tiles[j]) do
            begin
              s := s + '0{=' + IntToStr(j+k*(length(map.rooms[i].tiles[j]))) + '_';
              n := 0;
              for l := low(map.tileSets) to high(map.tileSets) do
                begin
                  if (map.rooms[i].tiles[j, k].tileSet = map.tileSets[l]) then
                    begin
                      n := l;
                    end;
                end;
              s := s + '0=' + IntToStr(n) + '_';
              if (map.rooms[i].tiles[j, k].isWater = true) then s := s + '1=' + '1' + '_';
              if (map.rooms[i].tiles[j, k].isWater = false) then s := s + '1=' + '0' + '_';
              if (map.rooms[i].tiles[j, k].isGorge = true) then s := s + '2=' + '1' + '_';
              if (map.rooms[i].tiles[j, k].isGorge = false) then s := s + '2=' + '0' + '_';
              if (map.rooms[i].tiles[j, k].isGhosty = true) then s := s + '3=' + '1' + '_';
              if (map.rooms[i].tiles[j, k].isGhosty = false) then s := s + '3=' + '0' + '_';
              s := s + '4=' + IntToStr(map.rooms[i].tiles[j, k].tileTexture) + '_';
              if (map.rooms[i].tiles[j, k].transparent = true) then s := s + '5=' + '1' + '_';
              if (map.rooms[i].tiles[j, k].transparent = false) then s := s + '5=' + '0' + '_';
              s := s + '0}=' + '1' + '_';
            end;
        end;
      for j := low(map.rooms[i].objects) to high(map.rooms[i].objects) do
        begin
          for k := low(map.rooms[i].objects[j]) to high(map.rooms[i].objects[j]) do
            begin
              s := s + '1{=' + IntToStr(j+k*(length(map.rooms[i].objects[j]))) + '_';
              n := 0;
              for l := low(map.tileSets) to high(map.tileSets) do
                begin
                  if (map.rooms[i].objects[j, k].texture = map.tileSets[l]) then
                    begin
                      n := l;
                    end;
                end;
              s := s + '0=' + IntToStr(n) + '_';
              for l := low(map.rooms[i].objects[j, k].actions) to high(map.rooms[i].objects[j, k].actions) do
                begin
                  s := s + '0{=' + IntToStr(l) + '_';
                  s := s + '0=' + map.rooms[i].objects[j, k].actions[l].actionType + '_';
                  s := s + '1=' + map.rooms[i].objects[j, k].actions[l].arguments + '_';
                  s := s + '0}=' + '4' + '_';
                end;
              s := s + '1=' + map.rooms[i].objects[j, k].objectType + '_';
              s := s + '2=' + map.rooms[i].objects[j, k].text1 + '_';
              s := s + '3=' + map.rooms[i].objects[j, k].text2 + '_';
              s := s + '4=' + IntToStr(map.rooms[i].objects[j, k].texturePosition) + '_';
              if (map.rooms[i].objects[j, k].isLiving = true) then s := s + '5=' + '1' + '_';
              if (map.rooms[i].objects[j, k].isLiving = false) then s := s + '5=' + '0' + '_';
              s := s + '1}=' + '1' + '_';
            end;
        end;
      s := s + '0}=' + '0' + '_';
    end;
  result := s;
end;

end.
